package yxy.game.pm2.module.player;

import java.util.Collection;

import yxy.apple.util.PubSub.MethodSubscriber;
import yxy.apple.util.PubSub.SubscriptionMethod;
import yxy.cherry.data.script.fomula;
import yxy.cherry.game.base.bean.GatewayBean;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.bean.pubsub.PlayerLevelPublisher;
import yxy.game.pm2.bean.pubsub.PlayerLevelPublisher.PlayerLevelSubscription;
import yxy.game.pm2.module.NotificationHandle;

public class WorldLevelHandle extends MethodSubscriber {
	static private WorldLevelHandle instance;

	public static WorldLevelHandle getInstance() {
		if (instance == null) {
			instance = new WorldLevelHandle();
			instance.init();
		}
		return instance;
	}

	private void init() {
		PlayerLevelPublisher.getInstance().subscribe(this);
	}

	private WorldLevelHandle() {
	}



	@SubscriptionMethod(Type = PlayerLevelSubscription.class)
	public void receive(PlayerLevelSubscription subscription) {
		PlayerBean playerBean = subscription.getPlayerBean();
		AreaBean areaBean = AreaModule.area(playerBean);

		try {
			if (areaBean.tryLock()) {
				RankPlayerLevel rankPlayerLevel = RankPlayerLevel.getRank(playerBean.getCode());
				rankPlayerLevel.put(playerBean.getCode(), playerBean.getLevel());

				int topsize = fomula.世界等级获取排名名次.intValue();
				Collection<RankEntry> entries = rankPlayerLevel.top(topsize);

				Long worldLevel = 0L;
				for (RankEntry entry : entries) {
					long level = entry.getValue();
					worldLevel += level;
				}
				worldLevel /= topsize;

				if (worldLevel <= 0) {
					worldLevel = 1L;
				}
				if (worldLevel == areaBean.getWorldLevel()) {
					return;
				}

				areaBean.setWorldLevel(worldLevel.intValue());
				areaBean.set();

				handleNotify(areaBean);
			}
		} catch (InterruptedException e) {
		} finally {
			areaBean.unlock();
		}

	}



	private void handleNotify(AreaBean areaBean) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				Collection<GatewayBean> all = GatewayBean.all(RedisManager.getInstance().getConnection(RedisType.REDIS_USER));
				NotificationHandle handle = new NotificationHandle();
				int worldLevel = areaBean.getWorldLevel();
				for (GatewayBean bean : all) {
					String playerCode = bean.getPcode();
					AreaBean area = AreaModule.area(playerCode);
					if (area.getAreaId() == areaBean.getAreaId()) {
						handle.notifyWorldLevel(playerCode, worldLevel);
					}
				}
			}
		}).start();
	}


	public static int getLevel(PlayerBean playerBean) {
		AreaBean area = AreaModule.area(playerBean);
		return area.getWorldLevel();
	}
}
